import { Vec2, Vec3, Camera, Node, EventTouch, EventMouse, rect, Label, game, Prefab, Size } from "cc"
import { ccclass, BaseScene, LoadDir, _config_, _guide, EPlatformType, _ui, Polygon, NodeHelper, IVector2, _timer, Maths, _logic, Rectangle, Sets, _main, RectHollow, Vector2, IGuideMaskUIText, BaseHollow, EventHandlerCC, ETweenType, TweenHelper, EUIState, _audio, EEntityState, _language, PoolOnce, Times, property, _platform, Move, _resouces, _gameType, winCenterPostion } from "../../main/script/Main"
import { EntityMgr } from "./EntityMgr"
import { CSceneData, EEntityType, ELogicDataState, ILogicData, ILogicNuoData } from "../../main/script/module/define/LogicDefine"
import { DragEntity } from "./entity/DragEntity"
import { EGameType } from "../../main/script/module/define/GameTypeDefine"
import { ISelectionEntityData, SelectionEntity } from "./entity/SelectionEntity"
import { CubeEntity } from "./entity/CubeEntity"
import { TenSceneLogic } from "./logic/TenSceneLogic"
import { NuoSceneLogic } from "./logic/NuoSceneLogic"
import { CubeNuoEntity } from "./entity/CubeNuoEntity"




const v2T = new Vec2()
const v2T2 = new Vector2()
const v3T = new Vec3()
const rectT = new Rectangle()
const sizeT = new Size()

@ccclass("Scene")
export class Scene extends BaseScene {

    public entityMgr = new EntityMgr(this)

    public cContent: Node = null!
    public cACube: Node = null!
    public cAEffect: Node = null!
    public cADragParent: Node = null!
    public cBorder: Node = null!

    public isIndexShow: boolean = true
    public isLoadComplete: boolean = false

    public animLoadDir = new LoadDir(-1, null!)
    public animLoadDir2 = new LoadDir(-1, null!)

    public _touchId: number = -1

    public touchMovePos = new Vec2()

    public ten: TenSceneLogic = null!
    public nuo: NuoSceneLogic = null!

    onLoad(): void {
        super.onLoad()
        this.cBorder.active = false
    }

    onCreate() {
        this.addEvent(_logic.EventType.RESET, this.guide, this, _logic)
        this.ten = new TenSceneLogic()
        this.nuo = new NuoSceneLogic()
    }

    onUpdate() {
        this.entityMgr.updateStateMachine()

        if (this.isLoadComplete)
            if (!_logic.isTenGameType)
                if (_timer.hasUpdateIntervale("scene_ten", 1 / 5, false)) {
                    let entites = this.entityMgr.entitesType.get(EEntityType.Cube)
                    let ys: CubeNuoEntity[] = []
                    entites.forEach<CubeNuoEntity>(v => {
                        if (v.enabledInHierarchy) {

                            let isAdd = false
                            for (let i = 0; i < ys.length; i++) {
                                let y = v.getZIndex()
                                if (ys[i].getZIndex() < y) {
                                    isAdd = true
                                    ys.splice(i, 0, v)
                                    break
                                }
                            }
                            if (!isAdd)
                                ys.push(v)
                        }
                    })

                    for (let i = 0; i < ys.length; i++)
                        ys[i].node.setSiblingIndex(i)
                }
    }

    public create() {
        this._createInit()
        if (_logic.isTenGameType)
            this.ten.create()
        else
            this.nuo.create()
    }

    public removeComplete() {
        if (_gameType.type == EGameType.tenLevel)
            _timer.once(this, () => {
                if (_platform.type != EPlatformType.oppo)
                    _platform._vibrate_.short()
                _audio.play("sceneRes/audio/remove")
                _ui.playParticle(CSceneData.removeParticle, Vector2.ZERO)
            }, .3)
        else
            _audio.play("sceneRes/audio/remove")

        _guide.closeFinger()
        _guide.closeMask()
        this.clearTips()
        this.guide()
    }

    public startAnim(
        count: number,
        create: (index: number) => void,
        getIndexs: (indexs: number[]) => void,
        complete: () => void,
    ) {
        if (_gameType.type != EGameType.index)
            _ui.blockTouchEvent(true)
        this.animLoadDir.count = count
        this.animLoadDir.onFinish = () => this.scheduleOnce(complete)

        let indexs: number[] = []
        getIndexs(indexs)

        let allAnimDuration = Maths.lerp(2, 1, 16 / count)
        let interval = allAnimDuration / count

        for (let i = 0; i < indexs.length; i++)
            this.scheduleOnce(() => {
                create(indexs[i])
            }, i * interval)

    }

    public guide(delay?: number) {
        switch (_gameType.type) {
            case EGameType.tenLevel: {
                let config = _logic._tenLevel.curConfig
                if (config.tip === 1)
                    this.scheduleOnceCover(this._guide, delay || 10)
                break
            }
            case EGameType.nuoLevel: {
                let config = _logic._nuoLevel.curConfig
                if (config.tip === 1)
                    this.scheduleOnceCover(this._guide, delay || 3)
                break
            }
            case EGameType.nuoToday: {
                let config = _logic._nuoToday.curConfig
                if (config.tip === 1)
                    this.scheduleOnceCover(this._guide, delay || 3)
                break
            }
        }
    }

    public clearTips() {
        _guide.closeFinger()
        _guide.closeMask()
        this.entityMgr.entitesType.get(EEntityType.Cube)
            .forEach<CubeEntity>(entity => {
                entity.tipAnimStop()
            })

        let drag = this.entityMgr.drag
        if (drag)
            drag.tipAnimStop()
    }

    private _guide() {
        if (_logic.isTenGameType)
            _logic.ten.propTip()
        else
            _logic.nuo.propTip()
    }

    public getIndexs(size: Vector2, indexs: number[], startIndex: number) {
        let maxX = size.x,
            maxY = size.y
        for (let y = 0; y < maxY; y++) {
            let arr: number[] = []
            for (let x = 0; x < maxX; x++)
                arr.push(x * maxY + y + startIndex)
            if (y % 2 != 0)
                arr.reverse()
            indexs.push(...arr)
        }
    }


    private _createInit() {
        this.isLoadComplete = false
        this.unscheduleAllCallbacks()
        _timer.clearAll(this)
        // 回收所有的
        this.entityMgr.clear(false)
        _guide.closeFinger()
        _guide.closeMask()
        this.cBorder.active = false
    }

    public touchStart(e: EventTouch) {
        if (!this.isLoadComplete)
            return

        if (this._touchId != -1)
            return
        this._touchId = e.getID()

        if (_logic.isTenGameType)
            this.ten.touchStart(e)
        else
            this.nuo.touchStart(e)
    }

    public touchEnd(e: EventTouch) {

        if (!this.isLoadComplete)
            return
        if (!(this._touchId != -1 && this._touchId == e.getID()))
            return
        this._touchId = -1
        if (_logic.isTenGameType)
            this.ten.touchEnd(e)
        else
            this.nuo.touchEnd(e)
    }


    public touchCancel(e: EventTouch) {
        if (!this.isLoadComplete)
            return
        if (!(this._touchId != -1 && this._touchId == e.getID()))
            return
        this._touchId = -1
        if (_logic.isTenGameType)
            this.ten.touchClear()
        else
            this.nuo.touchClear()
    }

    public touchMove(e: EventTouch) {
        if (!this.isLoadComplete)
            return
        if (!(this._touchId != -1 && this._touchId == e.getID()))
            return
        if (_logic.isTenGameType)
            this.ten.touchMove(e)
        else
            this.nuo.touchMove(e)

    }

    public mouseWheel(e: EventMouse) {

        if (!this.isLoadComplete)
            return
    }


    public getTouchPos(e: EventTouch) {
        e.getUILocation(this.touchMovePos)
        // 转换为节点内
        Vector2.sub(this.touchMovePos, this.touchMovePos, winCenterPostion())
    }


}

